﻿using DataCapture.Helper;
using Redbus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using MessageBox = System.Windows.MessageBox;

namespace DataCapture
{
    public partial class MainForm : Form
    {
        //互斥锁,防止应用程序的多个实例同时运行
        static Mutex mutex = new Mutex(true, "{HT_DataAcquisitionSystem_V0.0}");
        private int maxLogLines = 5000; // 设置最大显示行数
        static SynchronizationContext SyncContext = null;//跨线程更新UI界面
        List<SubscriptionToken> subscriptionTokens = new List<SubscriptionToken>();

        private static MainForm _instance;
        public static MainForm Instance
        {
            get { return _instance; }
        }

       
        protected bool _bStop = false;
        private CancellationTokenSource _cancellationTokenSource;
        
        public  MainForm()
        {
            if (!mutex.WaitOne(TimeSpan.Zero, true))
            {
                // 应用程序已经运行，可以选择退出或显示消息  
                MessageBox.Show("应用程序已经在运行！");
                this.Dispose();
                this.Close();
                return;
            }
            SyncContext = SynchronizationContext.Current;
            InitializeComponent();
            _instance = this;

            timer_TaskInfo.Interval = 10000;
            timer_TaskInfo.Start();

            //// 主动隐藏主窗口  
            //this.WindowState = FormWindowState.Minimized;
            //this.Hide();

        }

        private async void MainForm_Load(object sender, EventArgs e)
        {
            // 等待所有服务初始化完成
            bool allServicesReady = await InitHTRWCoreAsync();
            if (allServicesReady)
            {
                // 所有服务就绪后再开始数据采集
                btn_DeviceRealRead.PerformClick();
            }
            else
            {
                ShowInfo("部分服务初始化失败，无法启动数据采集");
            }

        }

        async Task<bool> InitHTRWCoreAsync()
        {
            bool isDbReady = false;
            //消息事件系统的token
            var token = EventBusHelper.EventBus().Subscribe<RWEventCommon<MessageLog>>(s =>
            {
                if (s.EventKey == "TRACE_LOG")
                {//显示日志
                    SyncContext.Post(UpdateLogEvent, s.Payload);
                }
                else if (s.EventKey == "ERROR")
                {//显示错误
                    SyncContext.Post(ProcessErrorEvent, s.Payload);
                }
               
            });
            subscriptionTokens.Add(token);
            //1.创建MQTT服务对象
            MQTTConsoleServer.Instance.GetHashCode();
            if (MQTTConsoleServer.Instance.MqttServer != null)
            {
                label5.Text = MQTTConsoleServer.Instance.MqttServer.IsStarted ? "MQTT服务已启动" : "启动MQTT服务";
            }
            //2.初始化PLC通信对象
            PLCProcessingHelper.Instance.GetHashCode();//三菱PLC通信对象 

            //3. 初始化数据库连接（异步检查）
            isDbReady = await InitDatabaseAsync();
            string strMsg= isDbReady ? "数据库连接成功" : "数据库无法连接";
            label6.Text = strMsg;
            ShowInfo($"数据库初始化：{strMsg}");

            


            return isDbReady;
        }

        // 异步初始化数据库连接
        async Task<bool> InitDatabaseAsync()
        {
            try
            {
                // 使用Dapper的异步查询检查连接
                var result = await DapperHelper.ConnectAsync();
                if (result)
                {
                    DapperHelper.Instance.isConnect = true;
                    label6.Text = "数据库连接成功";
                    Log4NetHelper.Info("数据库连接成功", true);
                    return true;
                }
            }
            catch (Exception ex)
            {
                MessageLog message = new MessageLog()
                {
                    logLevel = (int)Helper.LogLevel.Error,
                    message = "ERROR_DB_CONNECT_FAIL"
                };
                EventBusHelper.EventBus().PublishAsync(new RWEventCommon<MessageLog>("ERROR", message));
                label6.Text = "数据库无法连接";
                Log4NetHelper.Error($"数据库无法连接 {ex.Message}", true);
            }
            DapperHelper.Instance.isConnect = false;
            return false;
        }

        private void DeviceRealRead_Click(object sender, EventArgs e)
        {

            _cancellationTokenSource = new CancellationTokenSource();
            CancellationToken cancellationToken = _cancellationTokenSource.Token;
            btn_DeviceRealStop.Enabled = true;
            btn_DeviceRealRead.Enabled = false;

            ReadDeviceRealDataAsync(cancellationToken);
        }

        private void ReadDeviceRealDataAsync(CancellationToken cancellationToken)
        {
            /**/
            Log4NetHelper.Debug($"---------------------数据采集软件开始读取数据！------------------------------------",true);
            
            //设备数据处理
            _ = new DeviceDataProcessingHelper(cancellationToken);

            
            //报表数据
            //Task.Run(async () => { await ReadReportData(cancellationToken); }, cancellationToken);
            

        }

        //Stopwatch stopwatch = new Stopwatch();
        //stopwatch.Start();
        //stopwatch.Stop();
        //MessageBox.Show("总耗时：" + stopwatch.Elapsed.ToString());

        

        private void btn_DeviceRealClear_Click(object sender, EventArgs e)
        {
            this.richTextBox1.Text = string.Empty;
        }
        
        private void btn_DeviceRealStop_Click(object sender, EventArgs e)
        {
            if (_cancellationTokenSource != null)
            {
                _cancellationTokenSource?.Cancel();
                _cancellationTokenSource?.Dispose();
            }
            btn_DeviceRealStop.Enabled = false;
            btn_DeviceRealRead.Enabled = true;
        }

        private void ProcessErrorEvent(object e)
        {
            if ((e as string) == "ERROR_DB_CONNECT_FAIL")
            {
                MessageBox.Show("无法连接数据库，请检测局域网网络是否正常！");
                //Process.GetCurrentProcess().Kill();//结束当前进程 todo 是继续运行
            }
            else if ((e as string) == "ERROR_ProductInspection_DB_CONNECT_FAIL")
            {
                MessageBox.Show("无法连接产品检测数据库，请检测局域网网络是否正常！");
                //Process.GetCurrentProcess().Kill();//结束当前进程 todo 是继续运行
            }
        }
        /// <summary>
        /// 显示Log到UI面板
        /// </summary>
        /// <param name="e"></param>
        private void UpdateLogEvent(object e)
        {
            
            MessageLog logEntry = e as MessageLog;
            if (logEntry == null) return;
            ShowInfo(logEntry.message);
        }
        /// <summary>
        /// 窗口实时显示信息
        /// </summary>
        /// <param name="txtInfo">TextBox控件名</param>
        /// <param name="Info">文本内容</param>
        public void ShowInfo(string Info)
        {
            Invoke(new Action(() =>
            {
                // 如果日志行数超过最大值，移除旧的日志
                if (richTextBox1.Lines.Length > maxLogLines)
                {
                    richTextBox1.Select(0, richTextBox1.GetFirstCharIndexOfCurrentLine());
                    richTextBox1.SelectedText = string.Empty;
                }

                if (richTextBox1.InvokeRequired) // 检查是否需要在UI线程上调用  
                {
                    richTextBox1.Invoke(new Action<string>(ShowInfo), Info); // 使用Invoke在UI线程上调用ShowInfo  
                }
                else
                {
                    richTextBox1.AppendText($"{Convert.ToString(DateTime.Now)}: {Info} \n");
                    //richTextBox1.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") + Info);
                    //richTextBox1.AppendText(Environment.NewLine);   //换行
                    richTextBox1.ScrollToCaret(); //滚动条始终滚动到当前数据插入的位置
                }
            }));

        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            //取消关闭窗口
            e.Cancel = true;
            //最小化主窗口
            this.WindowState = FormWindowState.Minimized;
            //任务栏取消图标
            this.ShowInTaskbar = false;
        }


        //双击右下角图标就恢复窗口正常大小 。
        private void notifyIcon_Main_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                //还原窗体
                this.WindowState = FormWindowState.Normal;
                //任务显示
                this.ShowInTaskbar = true;
            }
            //激活窗体
            this.Activate();
        }

        private void TSMenuItem_Exit_Click(object sender, EventArgs e)
        {
            
            UnsubscribeEvents();
            MQTTConsoleServer.Instance.CloseMqtt();
            mutex.ReleaseMutex(); //释放互斥锁
            this.Dispose();
            this.Close();
        }
        /// <summary>
        /// 取消订阅
        /// </summary>
        private void UnsubscribeEvents()
        {
            foreach (var token in subscriptionTokens)
            {
                EventBusHelper.EventBus().Unsubscribe(token);
            }
        }
        /// <summary>
        /// 任务台账信息定时器 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer_TaskInfo_Tick(object sender, EventArgs e)
        {
            if (MQTTConsoleServer.Instance.MqttServer != null)
            {
                label5.Text = MQTTConsoleServer.Instance.MqttServer.IsStarted ? "MQTT服务已启动" : "启动MQTT服务";
            }

            if (DapperHelper.Instance.isConnect)
            {//目前两个数据库连接不一样，目前暂时放在一起
                DataProcessor.ReadTaskInfoData();//获取数据库数据

            }
        }
    }
}
